home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / exampleCode / games / IndiZone / gold / menuMethods.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  10.4 KB  |  412 lines

  1. /*
  2.  * The original copyright owners of the accompanying source code files have
  3.  * agreed to place such code into the public domain.  Accordingly, anyone
  4.  * who receives or obtains a copy of such source code is freely entitled to
  5.  * reproduce, use and otherwise exploit such code (including the right to
  6.  * make derivative works), at his/her own risk and expense, without any
  7.  * obligation or liability to the original copyright owners.
  8.  *
  9.  * We would appreciate (but do not require) that the following message be
  10.  * included in any derivative works:
  11.  *
  12.  * "Portions of this program were developed by Peter Broadwell, Rob Myers
  13.  * and Robin Schaufler while working in Silicon Valley."
  14.  *
  15.  * The accompanying source code files and related documentation materials
  16.  * are distributed on an "AS IS" basis, without any warranties or
  17.  * guarantees of any kind.  All implied warranties, including the implied
  18.  * warranties of merchantability and of fitness for any particular purpose,
  19.  * are expressly disclaimed.
  20.  */
  21. #include "gl.h"
  22. #include "geom.h"
  23. #include "class.h"
  24. #include "selectors.h"
  25. #include "classIds.h"
  26. #include "colors.h"
  27. #include "mbox.h"
  28. #include "panel.h"
  29. #include "menu.h"
  30. #include "pick.h"
  31. #include "objIds.h"
  32.  
  33. extern inst *clone();
  34.  
  35. extern menu menuTemplate;
  36. extern menu bhmenuTemplate;
  37. extern choice  choiceTemplate;
  38. extern choicef choicefTemplate;
  39.  
  40.     /*
  41.      *  initialize a function menu
  42.      */
  43.      panel *
  44. makeMenu(list, dad, f, ScrArea, nbuttons, receiver, baseSel, paintObj, lightObj)
  45.     register panel *list, *dad;
  46.     int f;
  47.     register rectangle *ScrArea;
  48.     point2d *nbuttons;
  49.     inst *receiver;
  50.     int baseSel;
  51.     Object paintObj, lightObj;
  52. {
  53.     register menu *aMenu;
  54.  
  55.     if ((aMenu = (menu *)clone(&menuTemplate)) == NULL)
  56.     return list;
  57.     
  58.     aMenu->base.next = list;
  59.     aMenu->base.kids = NULL;
  60.     aMenu->base.dad  = dad;
  61.     aMenu->base.area = *ScrArea;
  62.     aMenu->base.painter = paintObj;
  63.  
  64.     aMenu->flags      = f;
  65.     aMenu->nbuttons   = *nbuttons;
  66.     aMenu->curVal     = 0;
  67.     aMenu->receiver   = receiver;
  68.     aMenu->baseSelect = baseSel;
  69.     aMenu->highlight  = lightObj;
  70.  
  71.     return (panel *)aMenu;
  72. }
  73.  
  74.  
  75.     /*
  76.      *  initialize a function menu
  77.      */
  78.      panel *
  79. makeBHMenu(list, dad, f, ScrArea, nbuttons, receiver, baseSel,paintObj,lightObj)
  80.     register panel *list, *dad;
  81.     int f;
  82.     register rectangle *ScrArea;
  83.     point2d *nbuttons;
  84.     inst *receiver;
  85.     int baseSel;
  86.     Object paintObj, lightObj;
  87. {
  88.     register menu *aMenu;
  89.  
  90.     if ((aMenu = (menu *)clone(&bhmenuTemplate)) == NULL)
  91.     return list;
  92.     
  93.     aMenu->base.next = list;
  94.     aMenu->base.kids = NULL;
  95.     aMenu->base.dad  = dad;
  96.     aMenu->base.area = *ScrArea;
  97.     aMenu->base.painter = paintObj;
  98.  
  99.     aMenu->flags      = f;
  100.     aMenu->nbuttons   = *nbuttons;
  101.     aMenu->curVal     = 0;
  102.     aMenu->receiver   = receiver;
  103.     aMenu->baseSelect = baseSel;
  104.     aMenu->highlight  = lightObj;
  105.  
  106.     return (panel *)aMenu;
  107. }
  108.  
  109.     /*
  110.      *  initialize a multi-choice menu
  111.      */
  112.      panel *
  113. makeChoice(list, dad, f, ScrArea, nxb,nyb,curb, value,choices,paintObj,lightObj)
  114.     register panel *list, *dad;
  115.     int f;
  116.     register rectangle *ScrArea;
  117.     int nxb,nyb,curb;
  118.     int *value;
  119.     int *choices;
  120.     Object paintObj, lightObj;
  121. {
  122.     register choice *aChoice;
  123.  
  124.     if ((aChoice = (choice *)clone(&choiceTemplate)) == NULL)
  125.     return list;
  126.     
  127.     aChoice->base.next = list;
  128.     aChoice->base.kids = NULL;
  129.     aChoice->base.dad  = dad;
  130.     aChoice->base.area = *ScrArea;
  131.     aChoice->base.painter = paintObj;
  132.  
  133.     aChoice->flags      = f;
  134.     aChoice->nbuttons.x = nxb;
  135.     aChoice->nbuttons.y = nyb;
  136.     aChoice->curVal     = curb;
  137.     aChoice->baseChoice = choices;
  138.     aChoice->value      = value;
  139.     aChoice->highlight  = lightObj;
  140.  
  141.     return (panel *)aChoice;
  142. }
  143.  
  144.  
  145.     /*
  146.      *  initialize a floating point multi-choice menu
  147.      */
  148.      panel *
  149. makeChoicef(list, dad, f, ScrArea, nxb,nyb,curb,value,choices,paintObj,lightObj)
  150.     register panel *list, *dad;
  151.     int f;
  152.     register rectangle *ScrArea;
  153.     int nxb,nyb,curb;
  154.     Coord *value;
  155.     Coord *choices;
  156.     Object paintObj, lightObj;
  157. {
  158.     register choicef *aChoice;
  159.  
  160.     if ((aChoice = (choicef *)clone(&choicefTemplate)) == NULL)
  161.     return list;
  162.     
  163.     aChoice->base.next = list;
  164.     aChoice->base.kids = NULL;
  165.     aChoice->base.dad  = dad;
  166.     aChoice->base.area = *ScrArea;
  167.     aChoice->base.painter = paintObj;
  168.  
  169.     aChoice->flags      = f;
  170.     aChoice->nbuttons.x = nxb;
  171.     aChoice->nbuttons.y = nyb;
  172.     aChoice->curVal     = curb;
  173.     aChoice->baseChoice = choices;
  174.     aChoice->value      = value;
  175.     aChoice->highlight  = lightObj;
  176.  
  177.     return (panel *)aChoice;
  178. }
  179.  
  180.  
  181. #define interp(a,b,c) ((float)(a)/(float)(b)*(float)(c))
  182.  
  183.  
  184.     /*
  185.      *  draw a menu's highlight at hitstruct's position (tentative highlight)
  186.      */
  187. /* ARGSUSED */
  188. drawMenu(m, argtype, hit)
  189.     register menu *m;
  190.     long argtype;
  191.     register hitstruct *hit;
  192. {
  193.     point2d button;
  194.     point2df here;
  195.  
  196.     if (m->highlight) {
  197.     button.x = (int)((float)(hit->x * m->nbuttons.x + 0.5) /
  198.              (float)m->base.area.extent.x);
  199.     button.y = (int)((float)(hit->y * m->nbuttons.y + 0.5) /
  200.              (float)m->base.area.extent.y);
  201.  
  202.     here.x = interp(button.x, m->nbuttons.x, m->base.area.extent.x);
  203.     here.y = interp(button.y, m->nbuttons.y, m->base.area.extent.y);
  204.     globalPointf(m, &here);
  205.         /*
  206.     printf("drawMenu: plotting highlight at %g, %g\n", here.x, here.y);
  207.     printf("drawMenu: menu area %d, %d  %d, %d\n",
  208.               m->base.area.orig.x,
  209.               m->base.area.orig.y,
  210.               m->base.area.extent.x,
  211.               m->base.area.extent.y);
  212.         /* */
  213.  
  214.     pushmatrix();
  215.         translate(here.x, here.y, 0.0);
  216.         callobj(m->highlight);
  217.     popmatrix();
  218.     }
  219. }
  220.  
  221.  
  222.     /*
  223.      *  draw a choice's highlight at its current position
  224.      */
  225. drawChoice(c)
  226.     register choice *c;
  227. {
  228.     point2d curVal;
  229.  
  230.     if (c->highlight) {
  231.     curVal.x = c->curVal % c->nbuttons.x;
  232.     curVal.y = c->curVal / c->nbuttons.x;
  233.  
  234.     pushmatrix();
  235.         translate(interp(curVal.x, c->nbuttons.x, c->base.area.extent.x),
  236.               interp(curVal.y, c->nbuttons.y, c->base.area.extent.y),
  237.               0.0);
  238.         callobj(c->highlight);
  239.     popmatrix();
  240.     }
  241. }
  242.  
  243.  
  244.     /*
  245.      *  draw a floating point choice's highlight at its current position
  246.      */
  247. drawChoicef(c)
  248.     register choicef *c;
  249. {
  250.     point2d curVal;
  251.  
  252.     if (c->highlight) {
  253.     curVal.x = c->curVal % c->nbuttons.x;
  254.     curVal.y = c->curVal / c->nbuttons.x;
  255.  
  256.     pushmatrix();
  257.         translate(interp(curVal.x, c->nbuttons.x, c->base.area.extent.x),
  258.               interp(curVal.y, c->nbuttons.y, c->base.area.extent.y),
  259.               0.0);
  260.         callobj(c->highlight);
  261.     popmatrix();
  262.     }
  263. }
  264.  
  265.  
  266.     /*
  267.      * process a selection on a menu button
  268.      */
  269. /* ARGSUSED */
  270. selectMenu(self, argtype, hit)
  271.     register menu *self;
  272.     long argtype;
  273.     register hitstruct *hit;
  274. {
  275.     point2d button;
  276.  
  277.     button.x = (int)((float)(hit->x * self->nbuttons.x + 0.5) /
  278.              (float)self->base.area.extent.x);
  279.     button.y = (int)((float)(hit->y * self->nbuttons.y + 0.5) /
  280.              (float)self->base.area.extent.y);
  281.  
  282.     self->curVal = button.x + (button.y * self->nbuttons.x);
  283.  
  284. /*************
  285.     printf("selectMenu: button.x=%d, button.y=%d, curVal=%d\n",
  286.                         button.x, button.y, self->curVal);
  287.     printf("selectMenu: sending message %d to object 0x%x\n",
  288.                 self->baseSelect + self->curVal, self->receiver);
  289. /*************/
  290.  
  291.     /* dispatch a message to the menu's client */
  292.     Msg(self->receiver, self->baseSelect + self->curVal,
  293.             INTARG, self->baseSelect + self->curVal);
  294. }
  295.  
  296.     /*
  297.      * process a selection on a menu button
  298.      */
  299. /* ARGSUSED */
  300. cascadeMenu(self, argtype, hit)
  301.     register menu *self;
  302.     long argtype;
  303.     register hitstruct *hit;
  304. {
  305.     int flags;
  306.     point2d button;
  307.     panel *dad, *kids;
  308.     rectangle scrArea;
  309.  
  310.     button.x = 1;
  311.     button.y = 2;
  312.  
  313.     setrect(&scrArea, self->base.area.orig.x,
  314.               self->base.area.orig.y + self->base.area.extent.y,
  315.               235, 100);
  316.     makeobj(BHMENUOBJ);
  317.     fishColor(PANEL_WHITE);
  318.     rectfi(0,0, scrArea.extent.x, scrArea.extent.y);
  319.     fishColor(PANEL_GRAY3);
  320.     cmov2i(10, 10);
  321.     charstr("I'm tired of this behavior.");
  322.     cmov2i(20, 10+getheight());
  323.     charstr("Toss it away.");
  324.     cmov2i(10, 10+(scrArea.extent.y>>1));
  325.     charstr("Oops! I didn't mean to do this,");
  326.     cmov2i(20, 10+(scrArea.extent.y>>1)+getheight());
  327.     charstr("honest. Put me back where I was.");
  328.     closeobj();
  329.     makeobj(BHLITEOBJ);
  330.     fishColor(PANEL_GRAY3);
  331.     rectfi(5,5, scrArea.extent.x-10, (scrArea.extent.y>>1)-10);
  332.     closeobj();
  333.     dad = self->base.dad;
  334.     kids = dad->kids;
  335.     flags = NULL;
  336.     dad->kids = makeMenu(kids, dad, flags, &scrArea, &button, self->receiver,
  337.                    self->baseSelect, BHMENUOBJ, BHLITEOBJ);
  338. }
  339.  
  340.  
  341.     /*
  342.      * process a selection on a choice button
  343.      */
  344. selectChoice(self, argtype, hit)
  345.     register choice *self;
  346.     long argtype;
  347.     register hitstruct *hit;
  348. {
  349.     point2d button;
  350.  
  351.     button.x = (((hit->x - self->base.area.orig.x) * self->nbuttons.x + 0.5) /
  352.          self->base.area.extent.x);
  353.     button.y = (((hit->y - self->base.area.orig.y) * self->nbuttons.y + 0.5) /
  354.          self->base.area.extent.y);
  355.  
  356.     self->curVal = button.x + (button.y * self->nbuttons.x);
  357.  
  358.         /* draw the current highlight */
  359.     Msg(self, DRAWTRACKER, argtype, hit);
  360.  
  361.     /* printf("selectChoice: button.x=%d, button.y=%d, curVal=%d\n",
  362.                 button.x, button.y, self->curVal); /* */
  363.     if (self->value)
  364.     *(self->value) = self->baseChoice[self->curVal];
  365. }
  366.  
  367.  
  368.     /*
  369.      * process a selection on a floating point choice button
  370.      */
  371. selectChoicef(self, argtype, hit)
  372.     register choicef *self;
  373.     long argtype;
  374.     register hitstruct *hit;
  375. {
  376.     point2d button;
  377.  
  378.     button.x = (((hit->x - self->base.area.orig.x) * self->nbuttons.x + 0.5) /
  379.          self->base.area.extent.x);
  380.     button.y = (((hit->y - self->base.area.orig.y) * self->nbuttons.y + 0.5) /
  381.          self->base.area.extent.y);
  382.  
  383.     self->curVal = button.x + (button.y * self->nbuttons.x);
  384.  
  385.         /* draw the current highlight */
  386.     Msg(self, DRAWTRACKER, argtype, hit);
  387.  
  388.     /* printf("selectChoice: button.x=%d, button.y=%d, curVal=%d\n",
  389.                     button.x, button.y, self->curVal); /* */
  390.     if (self->value)
  391.     *(self->value) = self->baseChoice[self->curVal];
  392. }
  393.  
  394.  
  395. extern panel* curPanel;
  396.     /*
  397.      *  end picking on a menu (button goes up on it)
  398.      */
  399. eselMenu(self, argtype, hit)
  400.     register menu *self;
  401.     long argtype;
  402.     hitstruct *hit;
  403. {
  404.     /* printf("eselMenu:      END SELECT on 0x%x, class %d\n",
  405.                 self, ((inst *)self)->myClass->classId); /* */
  406.     if (curPanel == (panel *)self) {
  407.     convertHit(self, hit);
  408.     Msg(self, SELECT, argtype, hit);
  409.     Msg(self, TRANSACT, argtype, hit);
  410.     }
  411. }
  412.